#!/usr/bin/env node

const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');

// 颜色输出
const colors = {
  reset: '\x1b[0m',
  bright: '\x1b[1m',
  red: '\x1b[31m',
  green: '\x1b[32m',
  yellow: '\x1b[33m',
  blue: '\x1b[34m',
  cyan: '\x1b[36m',
};

function colorLog(color, message) {
  console.log(`${colors[color]}${message}${colors.reset}`);
}

function execCommand(command, options = {}) {
  try {
    return execSync(command, { 
      stdio: 'pipe', 
      encoding: 'utf8',
      ...options 
    });
  } catch (error) {
    return null;
  }
}

function analyzeCodeComplexity() {
  colorLog('blue', '📊 分析代码复杂度...');
  
  const srcPath = path.join(process.cwd(), 'src');
  const tauriSrcPath = path.join(process.cwd(), 'src-tauri', 'src');
  
  // 分析 TypeScript 代码
  if (fs.existsSync(srcPath)) {
    colorLog('cyan', '\n前端代码复杂度分析:');
    
    try {
      // 使用 ts-complexity 分析 TypeScript 代码
      const result = execCommand(`npx ts-complexity ${srcPath} --format json`);
      if (result) {
        const complexity = JSON.parse(result);
        console.log(`  平均复杂度: ${complexity.averageComplexity || 'N/A'}`);
        console.log(`  最高复杂度: ${complexity.maxComplexity || 'N/A'}`);
        console.log(`  复杂函数数量: ${complexity.complexFunctions?.length || 0}`);
      }
    } catch (error) {
      colorLog('yellow', '  ⚠️  TypeScript 复杂度分析工具不可用');
    }
    
    // 统计代码行数
    const tsFiles = execCommand(`find ${srcPath} -name "*.ts" -o -name "*.tsx" | wc -l`);
    const jsFiles = execCommand(`find ${srcPath} -name "*.js" -o -name "*.jsx" | wc -l`);
    const totalLines = execCommand(`find ${srcPath} -name "*.ts" -o -name "*.tsx" -o -name "*.js" -o -name "*.jsx" | xargs wc -l | tail -1`);
    
    console.log(`  TypeScript 文件: ${tsFiles?.trim() || 0}`);
    console.log(`  JavaScript 文件: ${jsFiles?.trim() || 0}`);
    console.log(`  总代码行数: ${totalLines?.trim().split(' ')[0] || 0}`);
  }
  
  // 分析 Rust 代码
  if (fs.existsSync(tauriSrcPath)) {
    colorLog('cyan', '\n后端代码复杂度分析:');
    
    try {
      // 使用 cargo-complexity 分析 Rust 代码
      const result = execCommand('cargo complexity --json', { cwd: 'src-tauri' });
      if (result) {
        const complexity = JSON.parse(result);
        console.log(`  平均复杂度: ${complexity.average || 'N/A'}`);
        console.log(`  最高复杂度: ${complexity.max || 'N/A'}`);
      }
    } catch (error) {
      colorLog('yellow', '  ⚠️  Rust 复杂度分析工具不可用');
    }
    
    // 统计 Rust 代码行数
    const rustFiles = execCommand(`find ${tauriSrcPath} -name "*.rs" | wc -l`);
    const totalLines = execCommand(`find ${tauriSrcPath} -name "*.rs" | xargs wc -l | tail -1`);
    
    console.log(`  Rust 文件: ${rustFiles?.trim() || 0}`);
    console.log(`  总代码行数: ${totalLines?.trim().split(' ')[0] || 0}`);
  }
}

function checkCodeDuplication() {
  colorLog('blue', '🔍 检查代码重复...');
  
  try {
    // 使用 jscpd 检查代码重复
    const result = execCommand('npx jscpd src --reporters json --output reports');
    if (result) {
      const report = JSON.parse(fs.readFileSync('reports/jscpd-report.json', 'utf8'));
      console.log(`  重复代码块: ${report.duplicates?.length || 0}`);
      console.log(`  重复率: ${report.statistics?.total?.percentage || 0}%`);
      
      if (report.duplicates?.length > 0) {
        colorLog('yellow', '  发现重复代码，请考虑重构');
        report.duplicates.slice(0, 5).forEach((dup, index) => {
          console.log(`    ${index + 1}. ${dup.firstFile?.name} (${dup.lines} 行)`);
        });
      }
    }
  } catch (error) {
    colorLog('yellow', '  ⚠️  代码重复检查工具不可用');
  }
}

function analyzeSecurityVulnerabilities() {
  colorLog('blue', '🔒 安全漏洞扫描...');
  
  // 扫描 npm 依赖
  colorLog('cyan', '\n前端依赖安全扫描:');
  try {
    const auditResult = execCommand('npm audit --json');
    if (auditResult) {
      const audit = JSON.parse(auditResult);
      const vulnerabilities = audit.metadata?.vulnerabilities || {};
      
      console.log(`  严重漏洞: ${vulnerabilities.critical || 0}`);
      console.log(`  高危漏洞: ${vulnerabilities.high || 0}`);
      console.log(`  中危漏洞: ${vulnerabilities.moderate || 0}`);
      console.log(`  低危漏洞: ${vulnerabilities.low || 0}`);
      
      if (vulnerabilities.critical > 0 || vulnerabilities.high > 0) {
        colorLog('red', '  ❌ 发现高危安全漏洞，请立即修复！');
      } else if (vulnerabilities.moderate > 0) {
        colorLog('yellow', '  ⚠️  发现中危安全漏洞，建议修复');
      } else {
        colorLog('green', '  ✅ 未发现高危安全漏洞');
      }
    }
  } catch (error) {
    colorLog('yellow', '  ⚠️  npm audit 失败');
  }
  
  // 扫描 Rust 依赖
  colorLog('cyan', '\n后端依赖安全扫描:');
  try {
    const auditResult = execCommand('cargo audit --json', { cwd: 'src-tauri' });
    if (auditResult) {
      const audit = JSON.parse(auditResult);
      const vulnerabilities = audit.vulnerabilities?.list || [];
      
      console.log(`  发现漏洞: ${vulnerabilities.length}`);
      
      if (vulnerabilities.length > 0) {
        colorLog('yellow', '  ⚠️  发现 Rust 依赖漏洞');
        vulnerabilities.slice(0, 3).forEach((vuln, index) => {
          console.log(`    ${index + 1}. ${vuln.package?.name}: ${vuln.advisory?.title}`);
        });
      } else {
        colorLog('green', '  ✅ 未发现 Rust 依赖漏洞');
      }
    }
  } catch (error) {
    colorLog('yellow', '  ⚠️  cargo audit 不可用或失败');
  }
}

function checkCodeStyle() {
  colorLog('blue', '🎨 代码风格检查...');
  
  // 检查前端代码风格
  colorLog('cyan', '\n前端代码风格:');
  try {
    execCommand('npm run lint', { stdio: 'inherit' });
    colorLog('green', '  ✅ ESLint 检查通过');
  } catch (error) {
    colorLog('red', '  ❌ ESLint 检查失败');
  }
  
  try {
    execCommand('npm run format:check', { stdio: 'inherit' });
    colorLog('green', '  ✅ Prettier 格式检查通过');
  } catch (error) {
    colorLog('red', '  ❌ Prettier 格式检查失败');
  }
  
  // 检查后端代码风格
  colorLog('cyan', '\n后端代码风格:');
  try {
    execCommand('cargo fmt --all -- --check', { cwd: 'src-tauri', stdio: 'inherit' });
    colorLog('green', '  ✅ Rust 格式检查通过');
  } catch (error) {
    colorLog('red', '  ❌ Rust 格式检查失败');
  }
  
  try {
    execCommand('cargo clippy --all-targets --all-features -- -D warnings', { 
      cwd: 'src-tauri', 
      stdio: 'inherit' 
    });
    colorLog('green', '  ✅ Clippy 检查通过');
  } catch (error) {
    colorLog('red', '  ❌ Clippy 检查失败');
  }
}

function generateQualityReport() {
  colorLog('blue', '📋 生成代码质量报告...');
  
  const report = {
    timestamp: new Date().toISOString(),
    project: 'Tauri Modern Template',
    version: JSON.parse(fs.readFileSync('package.json', 'utf8')).version,
    metrics: {
      complexity: {},
      duplication: {},
      security: {},
      style: {},
      coverage: {}
    }
  };
  
  // 获取测试覆盖率
  try {
    const coverageResult = execCommand('npm run test:unit:coverage -- --reporter=json');
    if (coverageResult) {
      const coverage = JSON.parse(coverageResult);
      report.metrics.coverage = {
        lines: coverage.total?.lines?.pct || 0,
        functions: coverage.total?.functions?.pct || 0,
        branches: coverage.total?.branches?.pct || 0,
        statements: coverage.total?.statements?.pct || 0
      };
    }
  } catch (error) {
    colorLog('yellow', '  ⚠️  无法获取测试覆盖率数据');
  }
  
  // 保存报告
  const reportsDir = path.join(process.cwd(), 'reports');
  if (!fs.existsSync(reportsDir)) {
    fs.mkdirSync(reportsDir, { recursive: true });
  }
  
  const reportPath = path.join(reportsDir, 'quality-report.json');
  fs.writeFileSync(reportPath, JSON.stringify(report, null, 2));
  
  colorLog('green', `✅ 质量报告已生成: ${reportPath}`);
  
  // 生成 HTML 报告
  generateHTMLReport(report);
}

function generateHTMLReport(report) {
  const htmlTemplate = `
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>代码质量报告 - ${report.project}</title>
    <style>
        body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; margin: 0; padding: 20px; background: #f5f5f5; }
        .container { max-width: 1200px; margin: 0 auto; background: white; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
        .header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 30px; border-radius: 8px 8px 0 0; }
        .content { padding: 30px; }
        .metric-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 20px; margin: 20px 0; }
        .metric-card { background: #f8f9fa; border-radius: 8px; padding: 20px; border-left: 4px solid #007bff; }
        .metric-value { font-size: 2em; font-weight: bold; color: #007bff; }
        .metric-label { color: #6c757d; margin-top: 5px; }
        .status-good { border-left-color: #28a745; }
        .status-warning { border-left-color: #ffc107; }
        .status-error { border-left-color: #dc3545; }
        .timestamp { color: #6c757d; font-size: 0.9em; }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>${report.project}</h1>
            <p>代码质量报告 - 版本 ${report.version}</p>
            <p class="timestamp">生成时间: ${new Date(report.timestamp).toLocaleString('zh-CN')}</p>
        </div>
        <div class="content">
            <h2>测试覆盖率</h2>
            <div class="metric-grid">
                <div class="metric-card ${report.metrics.coverage.lines > 80 ? 'status-good' : report.metrics.coverage.lines > 60 ? 'status-warning' : 'status-error'}">
                    <div class="metric-value">${report.metrics.coverage.lines || 0}%</div>
                    <div class="metric-label">行覆盖率</div>
                </div>
                <div class="metric-card ${report.metrics.coverage.functions > 80 ? 'status-good' : report.metrics.coverage.functions > 60 ? 'status-warning' : 'status-error'}">
                    <div class="metric-value">${report.metrics.coverage.functions || 0}%</div>
                    <div class="metric-label">函数覆盖率</div>
                </div>
                <div class="metric-card ${report.metrics.coverage.branches > 80 ? 'status-good' : report.metrics.coverage.branches > 60 ? 'status-warning' : 'status-error'}">
                    <div class="metric-value">${report.metrics.coverage.branches || 0}%</div>
                    <div class="metric-label">分支覆盖率</div>
                </div>
                <div class="metric-card ${report.metrics.coverage.statements > 80 ? 'status-good' : report.metrics.coverage.statements > 60 ? 'status-warning' : 'status-error'}">
                    <div class="metric-value">${report.metrics.coverage.statements || 0}%</div>
                    <div class="metric-label">语句覆盖率</div>
                </div>
            </div>
            
            <h2>建议</h2>
            <ul>
                ${report.metrics.coverage.lines < 80 ? '<li>建议提高测试覆盖率到 80% 以上</li>' : ''}
                <li>定期运行安全扫描，及时修复漏洞</li>
                <li>保持代码风格一致性</li>
                <li>监控代码复杂度，及时重构复杂函数</li>
            </ul>
        </div>
    </div>
</body>
</html>
`;
  
  const htmlPath = path.join(process.cwd(), 'reports', 'quality-report.html');
  fs.writeFileSync(htmlPath, htmlTemplate);
  colorLog('green', `✅ HTML 报告已生成: ${htmlPath}`);
}

async function main() {
  const args = process.argv.slice(2);
  const mode = args[0] || 'all';
  
  colorLog('cyan', '🔍 开始代码质量分析...');
  console.log('');
  
  try {
    switch (mode) {
      case 'complexity':
        analyzeCodeComplexity();
        break;
        
      case 'duplication':
        checkCodeDuplication();
        break;
        
      case 'security':
        analyzeSecurityVulnerabilities();
        break;
        
      case 'style':
        checkCodeStyle();
        break;
        
      case 'report':
        generateQualityReport();
        break;
        
      case 'all':
      default:
        analyzeCodeComplexity();
        checkCodeDuplication();
        analyzeSecurityVulnerabilities();
        checkCodeStyle();
        generateQualityReport();
        break;
    }
    
    colorLog('green', '\n✅ 代码质量分析完成！');
  } catch (error) {
    colorLog('red', `\n❌ 代码质量分析失败: ${error.message}`);
    process.exit(1);
  }
}

// 显示帮助信息
function showHelp() {
  console.log(`
${colors.bright}代码质量分析工具${colors.reset}

${colors.cyan}用法:${colors.reset}
  npm run quality [模式]

${colors.cyan}模式:${colors.reset}
  all           完整分析 (默认)
  complexity    代码复杂度分析
  duplication   代码重复检查
  security      安全漏洞扫描
  style         代码风格检查
  report        生成质量报告

${colors.cyan}示例:${colors.reset}
  npm run quality                 # 完整分析
  npm run quality complexity      # 复杂度分析
  npm run quality security        # 安全扫描
`);
}

if (require.main === module) {
  if (process.argv.includes('--help') || process.argv.includes('-h')) {
    showHelp();
    process.exit(0);
  }
  
  main().catch((error) => {
    colorLog('red', `❌ 代码质量分析失败: ${error.message}`);
    process.exit(1);
  });
}

module.exports = {
  analyzeCodeComplexity,
  checkCodeDuplication,
  analyzeSecurityVulnerabilities,
  checkCodeStyle,
  generateQualityReport,
};
